Модуль yaml | Tarantool
Документация на русском языке
поддерживается сообществом

Модуль yaml

The yaml module takes strings in YAML format and decodes them, or takes a series of non-YAML values and encodes them.

Ниже приведен перечень всех функций и элементов модуля yaml.

Имя Назначение
yaml.encode() Конвертация Lua-объекта в YAML-строку
yaml.decode() Конвертация YAML-строки в Lua-объект
__serialize parameter Output structure specification
yaml.cfg() Изменение конфигурации
yaml.NULL Аналог «nil» в языке Lua
yaml.encode(lua_value)

Конвертация Lua-объекта в YAML-строку.

Параметры:
  • lua_value – скалярное значение или значение из Lua-таблицы.
возвращает:

оригинальное значение, преобразованное в YAML-строку.

тип возвращаемого значения:
 

строка

yaml.decode(string)

Конвертация YAML-строки в Lua-объект.

Параметры:
  • string – строка в формате YAML.
возвращает:

оригинальное содержание в формате Lua-таблицы.

тип возвращаемого значения:
 

таблица

__serialize parameter:

The YAML output structure can be specified with __serialize:

  • 'seq', 'sequence', 'array': table encoded as an array
  • 'map', 'mapping': table encoded as a map
  • function: the meta-method called to unpack serializable representation of table, cdata, or userdata objects
tarantool> yaml.encode(setmetatable({'A', 'B'}, {__serialize='seq'}))
---
- |
  --- ['A', 'B']
  ...
...
tarantool> yaml.encode(setmetatable({'A', 'B'}, {__serialize='map'}))
---
- |
  --- {1: 'A', 2: 'B'}
  ...
...

'seq' or 'map' also enable the flow (compact) mode for the YAML serializer (flow="[1,2,3]" vs block=" - 1\n - 2\n - 3\n"). See the full example in the „Example“ section below.

yaml.cfg(table)

Set values affecting the behavior of encode and decode functions.

The values are all either integers or boolean true/false.

Характеристика Значение по умолчанию Назначение
cfg.encode_invalid_numbers true A flag saying whether to enable encoding of NaN and Inf numbers
cfg.encode_number_precision 14 Precision of floating point numbers
cfg.encode_load_metatables true A flag saying whether the serializer will follow __serialize metatable field
cfg.encode_use_tostring false A flag saying whether to use tostring() for unknown types
cfg.encode_invalid_as_nil false A flag saying whether to use NULL for non-recognized types
cfg.encode_sparse_convert true A flag saying whether to handle excessively sparse arrays as maps. See detailed description below
cfg.encode_sparse_ratio 2 1/encode_sparse_ratio is the permissible percentage of missing values in a sparse array
cfg.encode_sparse_safe 10 A limit ensuring that small Lua arrays are always encoded as sparse arrays (instead of generating an error or encoding as map)
cfg.decode_invalid_numbers true A flag saying whether to enable decoding of NaN and Inf numbers
cfg.decode_save_metatables true A flag saying whether to set metatables for all arrays and maps

Note on ``decode_save_metatables``

You may want to change the result’s metatable to get block-formatted encode() for better readability, but be careful to do it correctly.

Важно

Decoder uses globally defined tables as metatables for arrays and maps. You must not change entries of decode() result’s table metatable, because it affects all results and may lead to undefined behavior of other code.

The correct way is to assign a new metatable.

tarantool> t1 = yaml.decode(yaml.encode({[1] = 'a', x = 'b'}))
tarantool> yaml.encode(t1)
---
- |
  --- {'x': 'b', 1: 'a'}
  ...
...
tarantool> my_mt = {__serialize = 'mapping'}
tarantool> setmetatable(t1, my_mt)
tarantool> yaml.encode(t1)
---
- |
  ---
  x: b
  1: a
  ...
...

Do not change the metatable like this.

tarantool> t1 = yaml.decode(yaml.encode({[1] = 'a', x = 'b'}))
tarantool> getmetatable(t1).__serialize
---
- map
...
tarantool> getmetatable(t1).__serialize = 'mapping' -- (!) bad
tarantool> t2 = yaml.decode(yaml.encode({[1] = 'a', x = 'b'}))
tarantool> yaml.encode(t2) -- (!) got 'block' maps for all results
---
- |
  ---
  x: b
  1: a
  ...
...

Sparse arrays features:

During encoding, The YAML encoder tries to classify table into one of four kinds:

  • Map: at least one table index is not unsigned integer.
  • Regular array: all array indexes are available.
  • Sparse array: at least one array index is missing.
  • Excessively sparse array: the number of values missing exceeds the configured ratio.

An array is excessively sparse when all the following conditions are met:

  • encode_sparse_ratio > 0
  • max(table) > encode_sparse_safe
  • max(table) > count(table) * encode_sparse_ratio

The YAML encoder will never consider an array to be excessively sparse when encode_sparse_ratio = 0. The encode_sparse_safe limit ensures that small Lua arrays are always encoded as sparse arrays. By default, attempting to encode an excessively sparse array will generate an error. If encode_sparse_convert is set to true, excessively sparse arrays will be handled as maps.

yaml.cfg() example 1:

The following code will encode 0/0 as NaN («not a number») and 1/0 as Inf («infinity»), rather than returning nil or an error message:

yaml = require('yaml')
yaml.cfg{encode_invalid_numbers = true}
x = 0/0
y = 1/0
yaml.encode({1, x, y, 2})

Результат запроса yaml.encode() будет следующим:

tarantool> yaml.encode({1, x, y, 2})
---
- '[1,nan,inf,2]
...

yaml.cfg example 2:

To avoid generating errors on attempts to encode unknown data types as userdata/cdata, you can use this code:

tarantool> httpc = require('http.client').new()
---
...

tarantool> yaml.encode(httpc.curl)
---
- error: unsupported Lua type 'userdata'
...

tarantool> yaml.encode(httpc.curl, {encode_use_tostring=true})
---
- '"userdata: 0x010a4ef2a0"'
...

Примечание

To achieve the same effect for only one call to yaml.encode() (i.e. without changing the configuration permanently), you can use yaml.encode({1, x, y, 2}, {encode_invalid_numbers = true}).

Similar configuration settings exist for JSON and MsgPack.

yaml.NULL

Значение, сопоставимое с нулевым значением «nil» в языке Lua, которое можно использовать в качестве объекта-заполнителя в кортеже.

tarantool> yaml = require('yaml')
---
...
tarantool> y = yaml.encode({'a', 1, 'b', 2})
---
...
tarantool> z = yaml.decode(y)
---
...
tarantool> z[1], z[2], z[3], z[4]
---
- a
- 1
- b
- 2
...
tarantool> if yaml.NULL == nil then print('hi') end
hi
---
...

Набор YAML-стилей можно указать с помощью __serialize:

  • __serialize="sequence" or __serialize="array" for a Block Sequence array,
  • __serialize="seq" для массива последовательности потоков,
  • __serialize="mapping" для ассоциативного массива последовательности блоков,
  • __serialize="map" для ассоциативного массива последовательности потоков.

Serializing array- or map-like tables containing 'A' and 'B' with different __serialize values brings different results:

tarantool> yaml = require('yaml')
---
...
tarantool> yaml.encode(setmetatable({'A', 'B'}, {__serialize='seq'}))
---
- |
  --- ['A', 'B']
  ...
...
tarantool> yaml.encode(setmetatable({'A', 'B'}, {__serialize='map'}))
---
- |
  --- {1: 'A', 2: 'B'}
  ...
...
tarantool> array_like_table = {'A', 'B'}
tarantool> yaml.encode(setmetatable(array_like_table, {__serialize='seq'}))
---
- |
  --- ['A', 'B']
  ...
...
tarantool> yaml.encode(setmetatable(array_like_table, {__serialize='sequence'}))
tarantool> yaml.encode(setmetatable(array_like_table, {__serialize='array'}))
---
- |
  ---
  - A
  - B
  ...
...
tarantool> yaml.encode(setmetatable(array_like_table, {__serialize='map'}))
---
- |
  --- {1: 'A', 2: 'B'}
  ...
...
tarantool> yaml.encode(setmetatable(array_like_table, {__serialize='mapping'}))
---
- |
  ---
  1: A
  2: B
  ...
...
tarantool> map_like_table = {f1 = 'A', f2 = 'B'}
tarantool> yaml.encode(setmetatable(map_like_table, {__serialize='seq'}))
tarantool> yaml.encode(setmetatable(map_like_table, {__serialize='sequence'}))
tarantool> yaml.encode(setmetatable(map_like_table, {__serialize='array'}))
---
- |
  --- []
  ...
...
tarantool> yaml.encode(setmetatable(map_like_table, {__serialize='map'}))
---
- |
  --- {'f2': 'B', 'f1': 'A'}
  ...
...
tarantool> yaml.encode(setmetatable(map_like_table, {__serialize='mapping'}))
---
- |
  ---
  f2: B
  f1: A
  ...
...
Нашли ответ на свой вопрос?
Обратная связь